package linker

import "debug/elf"

// New an Output Section
func NewOutputSection(name string, typE uint32, flags uint64, index uint32) *OutputSection {
	o := &OutputSection{Chunk: NewChunk()}
	o.Name = name
	o.Shdr.Type = typE
	o.Shdr.Flags = flags
	o.Idx = index
	return o
}

func (o *OutputSection) CopyBuf(ctx *Context) {
	if o.Shdr.Type == uint32(elf.SHT_NOBITS) {
		return
	}

	base := ctx.Buf[o.Shdr.Offset:]
	for _, isec := range o.Members {
		isec.WriteTo(ctx, base[isec.Offset:])
	}
}

func GetOutputSection(ctx *Context, name string, typE, flags uint64) *OutputSection {
	name = GetOutputName(name, flags)
	flags = flags &^ uint64(elf.SHF_GROUP) &^
		uint64(elf.SHF_COMPRESSED) &^ uint64(elf.SHF_LINK_ORDER)
	find := func() *OutputSection {
		for _, osec := range ctx.OutputSections {
			if name == osec.Name && typE == uint64(osec.Shdr.Type) &&
				flags == osec.Shdr.Flags {
				return osec
			}
		}

		return nil
	}

	if osec := find(); osec != nil {
		return osec
	}

	osec := NewOutputSection(name, uint32(typE), flags, uint32(len(ctx.OutputSections)))
	ctx.OutputSections = append(ctx.OutputSections, osec)
	return osec
}

// DONE
